package com.feeyo.groundservice.composewidget.view.edit

import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.border
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import com.feeyo.groundservice.base_util.toastCenter
import com.feeyo.groundservice.composewidget.R
import com.feeyo.groundservice.composewidget.constant.NumberType
import com.feeyo.groundservice.composewidget.util.dimenToDp
import com.feeyo.groundservice.composewidget.util.dimenToSp
import com.feeyo.groundservice.composewidget.util.getNumberRegex
import com.feeyo.groundservice.composewidget.util.getNumberRegexTip
import com.feeyo.groundservice.composewidget.util.horizonShake
import com.feeyo.groundservice.composewidget.util.intervalClick
import com.feeyo.groundservice.composewidget.util.toComposeColor
import com.feeyo.groundservice.composewidget.view.util.HorizontalSpace

/**
 *作者：QLH on 2023-08-05
 *描述：自定义输入框：带边框和不带边框的
 */
/**
 * 圆角输入框 ,颜色参数可以根据需要进行扩展
 * @param onValueChange:输入框内容变化回调
 * @param content:输入框默认内容
 * @param modifier:自定义样式,默认高度30.dp
 * @param hint:提示文字
 * @param hintColor:提示文字颜色
 * @param hintSize:提示文字大小
 * @param enabled:是否可用
 * @param isError:是否显示错误信息
 * @param errorAnimation 错误信息显示动画
 * @param textStyle:输入框文字样式 颜色 大小 权重 ...,和Text的属性类似
 * @param readOnly:是否只读
 * @param singleLine:是否单行
 * @param cornerRadius:圆角大小
 * @param hasLeadingIcon:是否显示左侧图标
 * @param leadingIcon:左侧图标
 * @param hasTrailingIcon:是否显示右侧图标
 * @param trailingIcon:右侧图标
 * @param hasPwdIcon:是否有密码图标
 * @param pwdChar:密码占位字符
 * @param focusedTextColor:焦点状态下输入框文字颜色
 * @param unfocusedTextColor:非焦点状态下输入框文字颜色
 * @param cursorColor:光标颜色
 * @param focusedIndicatorColor:焦点状态下输入框下划线颜色
 * @param unfocusedIndicatorColor:非焦点状态下输入框下划线颜色
 * @param focusedContainerColor:焦点状态下输入框背景颜色
 * @param unfocusedContainerColor:非焦点状态下输入框背景颜色
 * @param focusedLeadingIconColor:焦点状态下左侧图标颜色
 * @param unfocusedLeadingIconColor:非焦点状态下左侧图标颜色
 * @param focusedTrailingIconColor:焦点状态下右侧图标颜色
 * @param unfocusedTrailingIconColor:非焦点状态下右侧图标颜色
 * @param colors:各种颜色，可以使用单参数也可以直接传入颜色值
 * @param horizontalPadding 左侧内边距
 * @param verticalPadding 右侧内边距
 * @param interactionSource:交互源
 * @param maxLines:最大行数
 * @param minLines:最小行数
 * @param imeAction 键盘动作
 * @param keyboardType: 键盘类型
 * @param decimalPlaces 小数点位数
 * @param numberType: 数字类型
 * @param keyboardActions:键盘选项
 * @param closeKeyBoard:关闭键盘回调
 * @param clearFocus:清除焦点回调
 * @param focusChange :焦点改变回调
 * @param rightAlignment 是否居右对齐
 * @param verticalAlignment 垂直对齐方式
 * @param endExtensionView 右侧扩展view
 * **/

@Composable
fun RoundedCornerTextField(
    modifier: Modifier = Modifier.height(R.dimen.d45.dimenToDp()),
    onValueChange: (String) -> Unit,
    content: String = "",
    hint: String = "",
    hintColor: Color = R.color.gray_99.toComposeColor(),
    hintSize: TextUnit = R.dimen.d12.dimenToSp(),
    enabled: Boolean = true,
    isError: Boolean = false,
    errorAnimation: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    readOnly: Boolean = false,
    singleLine: Boolean = false,
    cornerRadius: Dp = R.dimen.d0.dimenToDp(),
    hasLeadingIcon: Boolean = false,
    leadingIcon: Int = R.drawable.icon_search,
    hasTrailingIcon: Boolean = true,
    trailingIcon: Int = R.drawable.icon_edt_clear_gray,
    hasPwdIcon: Boolean = false,//是否有密码图标
    pwdChar: Char = '*',//，密码占位字符
    focusedTextColor: Color = R.color.black_33.toComposeColor(),
    unfocusedTextColor: Color = R.color.black_33.toComposeColor(),
    cursorColor: Color = R.color.blue_2E76EE.toComposeColor(),
    focusedIndicatorColor: Color = R.color.transparent.toComposeColor(),
    unfocusedIndicatorColor: Color = R.color.transparent.toComposeColor(),
    focusedContainerColor: Color = R.color.transparent.toComposeColor(),
    unfocusedContainerColor: Color = R.color.transparent.toComposeColor(),
    focusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedPwdIconColor: Color = focusedTrailingIconColor,
    unFocusedPwdIconColor: Color = unfocusedTrailingIconColor,
    colors: TextFieldColors? = null,
    horizontalPadding: Dp = R.dimen.d5.dimenToDp(),
    verticalPadding: Dp = horizontalPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    imeAction: ImeAction = ImeAction.Done,
    keyboardType: KeyboardType = KeyboardType.Text,
    decimalPlaces: Int = 0,
    numberType: NumberType = NumberType.NONE,
    keyboardActions: (String) -> Unit = {},
    closeKeyBoard: (() -> Unit) -> Unit = {},
    clearFocus: (() -> Unit) -> Unit = {},
    focusChange: (Boolean) -> Unit = {},
    rightAlignment: Boolean = false,
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    endExtensionView: (@Composable () -> Unit)? = null

) {
    var text by remember { mutableStateOf(content) }
    val softwareKeyboardController = LocalSoftwareKeyboardController.current

    val focusManager = LocalFocusManager.current
    //输入错误动画提示
    val shake = remember { mutableStateOf(false) }
    //键盘关闭
    val close = {
        softwareKeyboardController?.hide()
    }

    //焦点清除
    val clear = {
        focusManager.clearFocus(true)
    }

    //密码模式
    val pwdModule = remember { mutableStateOf(false) }

    val visualTransformation = remember(pwdModule.value) {
        if (pwdModule.value) {
            if (pwdChar == PasswordVisualTransformation().mask)
                PasswordVisualTransformation()
            else
                PasswordVisualTransformation(pwdChar)
        } else {
            VisualTransformation.None
        }
    }

    //各种颜色
    val lastColors = colors ?: TextFieldDefaults.colors().copy(
        focusedTextColor = focusedTextColor,
        unfocusedTextColor = unfocusedTextColor,
        focusedIndicatorColor = focusedIndicatorColor,
        unfocusedIndicatorColor = unfocusedIndicatorColor,
        errorTextColor = R.color.red_E34D59.toComposeColor(),
    )
    //定义文本Style，包括文本的颜色、字体大小等,必须要定义，否则使用默认的字体颜色,只影响输入框样式
    val lastTextColor = textStyle.color.takeOrElse {
        val focused = interactionSource.collectIsFocusedAsState().value
        when {
            !enabled -> lastColors.disabledTextColor
            isError -> lastColors.errorTextColor
            focused -> lastColors.focusedTextColor
            else -> lastColors.unfocusedTextColor
        }
    }

    val mergedTextStyle = textStyle.merge(TextStyle(color = lastTextColor))

    //最终的cursorColor
    val lastCursorColor = if (isError) lastColors.errorCursorColor else cursorColor

    //关闭键盘的方法 回调给外部
    closeKeyBoard(close)
    clearFocus(clear)

    val focus = remember { mutableStateOf(false) }

    CompositionLocalProvider(LocalTextSelectionColors provides lastColors.textSelectionColors) {
        BasicTextField(
            value = text,
            onValueChange = {
                if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
                    val regex = decimalPlaces.getNumberRegex(numberType)
                    regex.let { reg ->
                        if (it.isNotEmpty() && it.matches(reg.toRegex())) {
                            text = it
                            onValueChange(text)
                        } else if (it.isEmpty()) {
                            text = it
                            onValueChange(text)
                        } else {
                            if (errorAnimation) {
                                shake.value = !shake.value
                            }
                            val msg = decimalPlaces.getNumberRegexTip(numberType)
                            toastCenter(msg)
                        }
                    }
                } else {
                    text = it
                    onValueChange(text)
                }
            },
            enabled = enabled,
            readOnly = readOnly,
            textStyle = mergedTextStyle,
            keyboardOptions = KeyboardOptions(
                imeAction = imeAction,
                keyboardType = keyboardType
            ),
            keyboardActions = when (imeAction) {
                ImeAction.Search -> KeyboardActions(
                    onSearch = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )

                ImeAction.Send -> KeyboardActions(
                    onSend = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )

                else -> KeyboardActions(
                    onDone = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )
            },
            visualTransformation = visualTransformation,
            modifier = modifier.onFocusChanged {
                focus.value = it.isFocused
                focusChange(it.isFocused)
            }.horizonShake(shake),
            singleLine = singleLine,
            maxLines = maxLines,
            minLines = minLines,
            interactionSource = interactionSource,
            cursorBrush = SolidColor(lastCursorColor)
        ) { innerTextField ->
            //自定义外观样式：leading trailing pwd...
            Box(
                modifier = Modifier.fillMaxSize()
                    .background(
                        color = if (focus.value) focusedContainerColor else unfocusedContainerColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).padding(
                        horizontal = horizontalPadding,
                        vertical = verticalPadding
                    )
            ) {
                Row(
                    modifier = Modifier.fillMaxSize(),
                    verticalAlignment = verticalAlignment,
                    horizontalArrangement = if (rightAlignment) Arrangement.End else Arrangement.Start
                ) {
                    //leading
                    if (hasLeadingIcon) {
                        Icon(
                            painter = painterResource(leadingIcon),
                            contentDescription = null,
                            tint = if (focus.value) focusedLeadingIconColor else unfocusedLeadingIconColor
                        )
                        HorizontalSpace(5.dp)
                    }

                    //输入框主体部分
                    if (rightAlignment) {
                        Box(
                            contentAlignment = Alignment.CenterEnd
                        ) {
                            if (text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    } else {
                        Box(
                            modifier = Modifier.weight(1f),
                            contentAlignment = Alignment.CenterStart
                        ) {
                            if (text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    }

                    if (hasTrailingIcon && text.isNotEmpty()) {
                        HorizontalSpace(5.dp)
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            //清除
                            Icon(
                                painter = painterResource(trailingIcon),
                                contentDescription = null,
                                modifier = Modifier.intervalClick {
                                    text = ""
                                    onValueChange(text)
                                },
                                tint = if (focus.value) focusedTrailingIconColor else unfocusedTrailingIconColor
                            )

                            //密码显示隐藏
                            if (hasPwdIcon) {
                                HorizontalSpace(R.dimen.d10.dimenToDp())
                                Icon(
                                    painter = painterResource(
                                        if (pwdModule.value)
                                            R.drawable.icon_pwd_hide
                                        else
                                            R.drawable.icon_pwd_show
                                    ),
                                    contentDescription = null,
                                    modifier = Modifier.intervalClick {
                                        pwdModule.value = !pwdModule.value

                                    },
                                    tint = if (focus.value) focusedPwdIconColor else unFocusedPwdIconColor
                                )
                            }
                        }
                    }

                    endExtensionView?.let {
                        HorizontalSpace(R.dimen.d10.dimenToDp())
                        it()
                    }
                }
            }
        }
    }

    //外部content变化 修改输入框的内容
    LaunchedEffect(key1 = content) {
        if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
            val regex = decimalPlaces.getNumberRegex(numberType)
            regex.let { reg ->
                if (content.isNotEmpty() && content.matches(reg.toRegex())) {
                    text = content
                } else if (content.isEmpty()) {
                    text = content
                } else {
                    if (errorAnimation) {
                        shake.value = !shake.value
                    }
                    val msg = decimalPlaces.getNumberRegexTip(numberType)
                    toastCenter(msg)
                }
            }
        } else {
            text = content
        }
    }
}


/**
 * 圆角输入框 ,颜色参数可以根据需要进行扩展，默认选中光标直接定位到尾部
 * @param onValueChange:输入框内容变化回调
 * @param content:输入框默认内容
 * @param modifier:自定义样式,默认高度30.dp
 * @param hint:提示文字
 * @param hintColor:提示文字颜色
 * @param hintSize:提示文字大小
 * @param enabled:是否可用
 * @param isError:是否显示错误信息
 * @param errorAnimation 错误信息显示动画
 * @param textStyle:输入框文字样式 颜色 大小 权重 ...,和Text的属性类似
 * @param readOnly:是否只读
 * @param singleLine:是否单行
 * @param cornerRadius:圆角大小
 * @param hasLeadingIcon:是否显示左侧图标
 * @param leadingIcon:左侧图标
 * @param hasTrailingIcon:是否显示右侧图标
 * @param trailingIcon:右侧图标
 * @param hasPwdIcon:是否有密码图标
 * @param pwdChar:密码占位字符
 * @param focusedTextColor:焦点状态下输入框文字颜色
 * @param unfocusedTextColor:非焦点状态下输入框文字颜色
 * @param cursorColor:光标颜色
 * @param focusedIndicatorColor:焦点状态下输入框下划线颜色
 * @param unfocusedIndicatorColor:非焦点状态下输入框下划线颜色
 * @param focusedContainerColor:焦点状态下输入框背景颜色
 * @param unfocusedContainerColor:非焦点状态下输入框背景颜色
 * @param focusedLeadingIconColor:焦点状态下左侧图标颜色
 * @param unfocusedLeadingIconColor:非焦点状态下左侧图标颜色
 * @param focusedTrailingIconColor:焦点状态下右侧图标颜色
 * @param unfocusedTrailingIconColor:非焦点状态下右侧图标颜色
 * @param focusedPwdIconColor:焦点状态下密码图标颜色
 * @param unFocusedPwdIconColor:非焦点状态下密码图标颜色
 * @param colors:各种颜色，可以使用单参数也可以直接传入颜色值
 * @param horizontalPadding 左侧内边距
 * @param verticalPadding 右侧内边距
 * @param interactionSource:交互源
 * @param maxLines:最大行数
 * @param minLines:最小行数
 * @param imeAction 键盘动作
 * @param keyboardType:键盘类型
 * @param decimalPlaces 小数点位数
 * @param numberType:数字类型
 * @param keyboardActions :键盘动作回调
 * @param closeKeyBoard:关闭键盘回调
 * @param clearFocus:清除焦点回调
 * @param focusChange :焦点改变回调
 * @param rightAlignment 是否右对齐
 * @param verticalAlignment 垂直对齐方式
 * @param endExtensionView:右侧扩展view
 * **/

@Composable
fun RoundedCornerTextFieldValue(
    modifier: Modifier = Modifier.height(R.dimen.d45.dimenToDp()),
    onValueChange: (String) -> Unit,
    content: String = "",
    hint: String = "",
    hintColor: Color = R.color.gray_99.toComposeColor(),
    hintSize: TextUnit = R.dimen.d12.dimenToSp(),
    enabled: Boolean = true,
    isError: Boolean = false,
    errorAnimation: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    readOnly: Boolean = false,
    singleLine: Boolean = false,
    cornerRadius: Dp = R.dimen.d0.dimenToDp(),
    hasLeadingIcon: Boolean = false,
    leadingIcon: Int = R.drawable.icon_search,
    hasTrailingIcon: Boolean = true,
    trailingIcon: Int = R.drawable.icon_edt_clear_gray,
    hasPwdIcon: Boolean = false,//是否有密码图标
    pwdChar: Char = '*',//，密码占位字符
    focusedTextColor: Color = R.color.black_33.toComposeColor(),
    unfocusedTextColor: Color = R.color.black_33.toComposeColor(),
    cursorColor: Color = R.color.blue_2E76EE.toComposeColor(),
    focusedIndicatorColor: Color = R.color.transparent.toComposeColor(),
    unfocusedIndicatorColor: Color = R.color.transparent.toComposeColor(),
    focusedContainerColor: Color = R.color.transparent.toComposeColor(),
    unfocusedContainerColor: Color = R.color.transparent.toComposeColor(),
    focusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedPwdIconColor: Color = focusedTrailingIconColor,
    unFocusedPwdIconColor: Color = unfocusedTrailingIconColor,
    colors: TextFieldColors? = null,
    horizontalPadding: Dp = R.dimen.d5.dimenToDp(),
    verticalPadding: Dp = horizontalPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    imeAction: ImeAction = ImeAction.Done,
    keyboardType: KeyboardType = KeyboardType.Text,
    decimalPlaces: Int = 0,
    numberType: NumberType = NumberType.NONE,
    keyboardActions: (String) -> Unit = {},
    closeKeyBoard: (() -> Unit) -> Unit = {},
    clearFocus: (() -> Unit) -> Unit = {},
    focusChange: (Boolean) -> Unit = {},
    rightAlignment: Boolean = false,
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    endExtensionView: (@Composable () -> Unit)? = null

) {
    var text by remember {
        mutableStateOf(
            TextFieldValue(
                text = content,
                selection = TextRange(content.length),
                composition = null
            )
        )
    }
    val softwareKeyboardController = LocalSoftwareKeyboardController.current

    val focusManager = LocalFocusManager.current
    //输入错误动画提示
    val shake = remember { mutableStateOf(false) }
    //键盘关闭
    val close = {
        softwareKeyboardController?.hide()
    }

    //焦点清除
    val clear = {
        focusManager.clearFocus(true)
    }

    //密码模式
    val pwdModule = remember { mutableStateOf(false) }

    val visualTransformation = remember(pwdModule.value) {
        if (pwdModule.value) {
            if (pwdChar == PasswordVisualTransformation().mask)
                PasswordVisualTransformation()
            else
                PasswordVisualTransformation(pwdChar)
        } else {
            VisualTransformation.None
        }
    }

    //各种颜色
    val lastColors = colors ?: TextFieldDefaults.colors().copy(
        focusedTextColor = focusedTextColor,
        unfocusedTextColor = unfocusedTextColor,
        focusedIndicatorColor = focusedIndicatorColor,
        unfocusedIndicatorColor = unfocusedIndicatorColor
    )
    //定义文本Style，包括文本的颜色、字体大小等,必须要定义，否则使用默认的字体颜色
    val lastTextColor = textStyle.color.takeOrElse {
        val focused = interactionSource.collectIsFocusedAsState().value
        when {
            !enabled -> lastColors.disabledTextColor
            isError -> lastColors.errorTextColor
            focused -> lastColors.focusedTextColor
            else -> lastColors.unfocusedTextColor
        }
    }

    val mergedTextStyle = textStyle.merge(TextStyle(color = lastTextColor))

    //最终的cursorColor
    val lastCursorColor = if (isError) lastColors.errorCursorColor else cursorColor

    //关闭键盘的方法 回调给外部
    closeKeyBoard(close)
    clearFocus(clear)

    val focus = remember { mutableStateOf(false) }

    CompositionLocalProvider(LocalTextSelectionColors provides lastColors.textSelectionColors) {
        BasicTextField(
            value = text,
            onValueChange = {
                if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
                    val regex = decimalPlaces.getNumberRegex(numberType)
                    regex.let { reg ->
                        if (it.text.isNotEmpty() && it.text.matches(reg.toRegex())) {
                            text = it
                            onValueChange(text.text)
                        } else if (it.text.isEmpty()) {
                            text = it
                            onValueChange(text.text)
                        } else {
                            if (errorAnimation) {
                                shake.value = !shake.value
                            }
                            val msg = decimalPlaces.getNumberRegexTip(numberType)
                            toastCenter(msg)
                        }
                    }
                } else {
                    text = it
                    onValueChange(text.text)
                }
            },
            enabled = enabled,
            readOnly = readOnly,
            textStyle = mergedTextStyle,
            keyboardOptions = KeyboardOptions(
                imeAction = imeAction,
                keyboardType = keyboardType
            ),
            keyboardActions = when (imeAction) {
                ImeAction.Search -> KeyboardActions(
                    onSearch = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )

                ImeAction.Send -> KeyboardActions(
                    onSend = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )

                else -> KeyboardActions(
                    onDone = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )
            },
            visualTransformation = visualTransformation,
            modifier = modifier.onFocusChanged {
                focus.value = it.isFocused
                focusChange(it.isFocused)
            }.horizonShake(shake),
            singleLine = singleLine,
            maxLines = maxLines,
            minLines = minLines,
            interactionSource = interactionSource,
            cursorBrush = SolidColor(lastCursorColor)
        ) { innerTextField ->
            //自定义外观样式：leading trailing pwd...
            Box(
                modifier = Modifier.fillMaxSize()
                    .background(
                        color = if (focus.value) focusedContainerColor else unfocusedContainerColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).padding(
                        horizontal = horizontalPadding,
                        vertical = verticalPadding
                    )
            ) {
                Row(
                    modifier = Modifier.fillMaxSize(),
                    verticalAlignment = verticalAlignment,
                    horizontalArrangement = if (rightAlignment) Arrangement.End else Arrangement.Start
                ) {
                    //leading
                    if (hasLeadingIcon) {
                        Icon(
                            painter = painterResource(leadingIcon),
                            contentDescription = null,
                            tint = if (focus.value) focusedLeadingIconColor else unfocusedLeadingIconColor
                        )
                        HorizontalSpace(5.dp)
                    }

                    //输入框主体部分
                    if (rightAlignment) {
                        Box(
                            contentAlignment = Alignment.CenterEnd
                        ) {
                            if (text.text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    } else {
                        Box(
                            modifier = Modifier.weight(1f),
                            contentAlignment = Alignment.CenterStart
                        ) {
                            if (text.text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    }

                    if (hasTrailingIcon && text.text.isNotEmpty()) {
                        HorizontalSpace(5.dp)
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            //清除
                            Icon(
                                painter = painterResource(trailingIcon),
                                contentDescription = null,
                                modifier = Modifier.intervalClick {
                                    text = TextFieldValue(
                                        text = "",
                                        selection = TextRange(0, 0)
                                    )
                                    onValueChange(text.text)
                                },
                                tint = if (focus.value) focusedTrailingIconColor else unfocusedTrailingIconColor
                            )

                            //密码显示隐藏
                            if (hasPwdIcon) {
                                HorizontalSpace(R.dimen.d10.dimenToDp())
                                Icon(
                                    painter = painterResource(
                                        if (pwdModule.value)
                                            R.drawable.icon_pwd_hide
                                        else
                                            R.drawable.icon_pwd_show
                                    ),
                                    contentDescription = null,
                                    modifier = Modifier.intervalClick {
                                        pwdModule.value = !pwdModule.value

                                    },
                                    tint = if (focus.value) focusedPwdIconColor else unFocusedPwdIconColor
                                )
                            }
                        }
                    }

                    endExtensionView?.let {
                        HorizontalSpace(R.dimen.d10.dimenToDp())
                        it()
                    }
                }
            }
        }
    }

    //外部content变化 修改输入框的内容
    LaunchedEffect(key1 = content) {

        if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
            val regex = decimalPlaces.getNumberRegex(numberType)
            regex.let { reg ->
                if (content.isNotEmpty() && content.matches(reg.toRegex())) {
                    text = TextFieldValue(
                        text = content,
                        selection = TextRange(content.length)
                    )
                } else if (content.isEmpty()) {
                    text = TextFieldValue(
                        text = content,
                        selection = TextRange(content.length)
                    )
                } else {
                    if (errorAnimation) {
                        shake.value = !shake.value
                    }
                    val msg = decimalPlaces.getNumberRegexTip(numberType)
                    toastCenter(msg)
                }
            }
        } else {
            text = TextFieldValue(
                text = content,
                selection = TextRange(content.length)
            )
        }
    }
}

/**
 * 圆角带边框输入框 ,颜色参数可以根据需要进行扩展
 * @param onValueChange:输入框内容变化回调
 * @param content:输入框默认内容
 * @param modifier:自定义样式,默认高度30.dp
 * @param hint:提示文字
 * @param hintColor 提示文字颜色
 * @param hintSize:提示文字大小
 * @param enabled:是否可用
 * @param isError:是否显示错误信息
 * @param errorAnimation 错误信息显示动画
 * @param textStyle:输入框文字样式 颜色 大小 权重 ...,和Text的属性类似
 * @param readOnly:是否只读
 * @param singleLine:是否单行
 * @param cornerRadius:圆角大小
 * @param focusedBorderThickness:焦点状态下输入框边框宽度
 * @param unfocusedBorderThickness:非焦点状态下输入框边框宽度
 * @param hasLeadingIcon:是否显示左侧图标
 * @param leadingIcon 左侧图标
 * @param hasTrailingIcon:是否显示右侧图标
 * @param trailingIcon 右侧图标
 * @param hasPwdIcon:右侧是否有密码图标
 * @param pwdChar 密码占位字符
 * @param focusedTextColor:焦点状态下文字颜色
 * @param unfocusedTextColor:非焦点状态下文字颜色
 * @param cursorColor:光标颜色
 * @param focusedBorderColor:焦点状态下输入框边框颜色
 * @param unfocusedBorderColor:非焦点状态下输入框边框颜色
 * @param focusedContainerColor:焦点状态下输入框背景颜色
 * @param unfocusedContainerColor:非焦点状态下输入框背景颜色
 * @param focusedLeadingIconColor:焦点状态下左侧图标颜色
 * @param unfocusedLeadingIconColor:非焦点状态下左侧图标颜色
 * @param focusedTrailingIconColor:焦点状态下右侧图标颜色
 * @param unfocusedTrailingIconColor:非焦点状态下右侧图标颜色
 * @param focusedPwdIconColor:焦点状态下密码图标颜色
 * @param unFocusedPwdIconColor:非焦点状态下密码图标颜色
 * @param colors:各种颜色，可以使用单参数也可以直接传入颜色值
 * @param horizontalPadding 左侧内边距
 * @param verticalPadding 右侧内边距
 * @param interactionSource:交互源
 * @param maxLines:最大行数
 * @param minLines:最小行数
 * @param imeAction 键盘动作
 * @param keyboardType:键盘类型
 * @param keyboardActions :键盘动作回调
 * @param decimalPlaces 小数点位数
 * @param numberType:数字类型
 * @param closeKeyBoard:关闭键盘回调
 * @param clearFocus:清除焦点回调
 * @param focusChange :焦点改变回调
 * @param rightAlignment 是否右对齐
 * @param verticalAlignment 垂直对齐方式
 * @param endExtensionView:右侧扩展view
 * **/

@Composable
fun RoundedCornerOutlinedTextField(
    modifier: Modifier = Modifier.height(R.dimen.d45.dimenToDp()),
    onValueChange: (String) -> Unit,
    content: String = "",
    hint: String = "",
    hintColor: Color = R.color.gray_99.toComposeColor(),
    hintSize: TextUnit = R.dimen.d12.dimenToSp(),
    enabled: Boolean = true,
    isError: Boolean = false,
    errorAnimation: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    readOnly: Boolean = false,
    singleLine: Boolean = false,
    cornerRadius: Dp = R.dimen.d0.dimenToDp(),
    focusedBorderThickness: Dp = R.dimen.d1.dimenToDp(),
    unfocusedBorderThickness: Dp = R.dimen.d1.dimenToDp(),
    hasLeadingIcon: Boolean = false,
    leadingIcon: Int = R.drawable.icon_search,
    hasTrailingIcon: Boolean = true,
    trailingIcon: Int = R.drawable.icon_edt_clear_gray,
    hasPwdIcon: Boolean = false,//是否有密码图标
    pwdChar: Char = '*',//，密码占位字符
    focusedTextColor: Color = R.color.black_33.toComposeColor(),
    unfocusedTextColor: Color = R.color.black_33.toComposeColor(),
    cursorColor: Color = R.color.blue_2E76EE.toComposeColor(),
    focusedBorderColor: Color = R.color.blue_2E76EE.toComposeColor(),
    unfocusedBorderColor: Color = R.color.gray_99.toComposeColor(),
    focusedContainerColor: Color = R.color.transparent.toComposeColor(),
    unfocusedContainerColor: Color = R.color.transparent.toComposeColor(),
    focusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedPwdIconColor: Color = focusedTrailingIconColor,
    unFocusedPwdIconColor: Color = unfocusedTrailingIconColor,
    colors: TextFieldColors? = null,
    horizontalPadding: Dp = R.dimen.d5.dimenToDp(),
    verticalPadding: Dp = horizontalPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    imeAction: ImeAction = ImeAction.Done,
    keyboardType: KeyboardType = KeyboardType.Text,
    decimalPlaces: Int = 0,
    numberType: NumberType = NumberType.NONE,
    keyboardActions: (String) -> Unit = {},
    closeKeyBoard: (() -> Unit) -> Unit = {},
    clearFocus: (() -> Unit) -> Unit = {},
    focusChange: (Boolean) -> Unit = {},
    rightAlignment: Boolean = false,
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    endExtensionView: (@Composable () -> Unit)? = null
) {
    var text by remember { mutableStateOf(content) }
    val softwareKeyboardController = LocalSoftwareKeyboardController.current

    val focusManager = LocalFocusManager.current
    //输入错误动画提示
    val shake = remember { mutableStateOf(false) }
    //键盘关闭
    val close = {
        softwareKeyboardController?.hide()
    }

    //焦点清除
    val clear = {
        focusManager.clearFocus(true)
    }

    //密码是否可见
    val pwdModule = remember { mutableStateOf(false) }

    val visualTransformation = remember(pwdModule.value) {
        if (pwdModule.value) {
            if (pwdChar == PasswordVisualTransformation().mask)
                PasswordVisualTransformation()
            else
                PasswordVisualTransformation(pwdChar)
        } else {
            VisualTransformation.None
        }
    }

    //定义颜色
    val lastColors = colors ?: OutlinedTextFieldDefaults.colors(
        focusedTextColor = focusedTextColor,
        unfocusedTextColor = unfocusedTextColor,
    )

    //定义文本Style，包括文本的颜色、字体大小等,必须要定义，否则使用默认的字体颜色
    val lastTextColor = textStyle.color.takeOrElse {
        val focused = interactionSource.collectIsFocusedAsState().value
        when {
            !enabled -> lastColors.disabledTextColor
            isError -> lastColors.errorTextColor
            focused -> lastColors.focusedTextColor
            else -> lastColors.unfocusedTextColor
        }
    }

    val mergedTextStyle = textStyle.merge(TextStyle(color = lastTextColor))

    //最终的cursorColor
    val lastCursorColor = if (isError) lastColors.errorCursorColor else cursorColor

    //关闭键盘的方法 回调给外部
    closeKeyBoard(close)
    clearFocus(clear)

    val focus = remember { mutableStateOf(false) }

    CompositionLocalProvider(LocalTextSelectionColors provides lastColors.textSelectionColors) {
        BasicTextField(
            value = text,
            onValueChange = {
                if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
                    val regex = decimalPlaces.getNumberRegex(numberType)
                    regex.let { reg ->
                        if (it.isNotEmpty() && it.matches(reg.toRegex())) {
                            text = it
                            onValueChange(text)
                        } else if (it.isEmpty()) {
                            text = it
                            onValueChange(text)
                        } else {
                            if (errorAnimation) {
                                shake.value = !shake.value
                            }
                            val msg = decimalPlaces.getNumberRegexTip(numberType)
                            toastCenter(msg)
                        }
                    }
                } else {
                    text = it
                    onValueChange(text)
                }
            },
            keyboardOptions = KeyboardOptions(
                imeAction = imeAction,
                keyboardType = keyboardType
            ),
            keyboardActions = when (imeAction) {
                ImeAction.Search -> KeyboardActions(
                    onSearch = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )

                ImeAction.Send -> KeyboardActions(
                    onSend = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )

                else -> KeyboardActions(
                    onDone = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text)
                    },
                )
            },
            visualTransformation = visualTransformation,
            modifier = modifier.onFocusChanged {
                focus.value = it.isFocused
                focusChange(it.isFocused)
            }.horizonShake(shake),
            enabled = enabled,
            readOnly = readOnly,
            textStyle = mergedTextStyle,
            singleLine = singleLine,
            maxLines = maxLines,
            minLines = minLines,
            interactionSource = interactionSource,
            cursorBrush = SolidColor(lastCursorColor)
        ) { innerTextField ->
            //自定义外观样式：leading trailing pwd...
            Box(
                modifier = Modifier.fillMaxSize()
                    .background(
                        color = if (focus.value) focusedContainerColor else unfocusedContainerColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).border(
                        width = if (focus.value) focusedBorderThickness else unfocusedBorderThickness,
                        color = if (focus.value) focusedBorderColor else unfocusedBorderColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).padding(
                        horizontal = horizontalPadding,
                        vertical = verticalPadding
                    )
            ) {
                Row(
                    modifier = Modifier.fillMaxSize(),
                    verticalAlignment = verticalAlignment,
                    horizontalArrangement = if (rightAlignment) Arrangement.End else Arrangement.Start
                ) {
                    //leading
                    if (hasLeadingIcon) {
                        Icon(
                            painter = painterResource(leadingIcon),
                            contentDescription = null,
                            tint = if (focus.value) focusedLeadingIconColor else unfocusedLeadingIconColor
                        )
                        HorizontalSpace(5.dp)
                    }

                    //输入框主体部分
                    if (rightAlignment) {
                        Box(
                            contentAlignment = Alignment.CenterEnd
                        ) {
                            if (text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    } else {
                        Box(
                            modifier = Modifier.weight(1f),
                            contentAlignment = Alignment.CenterStart
                        ) {
                            if (text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    }

                    if (hasTrailingIcon && text.isNotEmpty()) {
                        HorizontalSpace(5.dp)
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            //清除
                            Icon(
                                painter = painterResource(trailingIcon),
                                contentDescription = null,
                                modifier = Modifier.intervalClick {
                                    text = ""
                                    onValueChange(text)
                                },
                                tint = if (focus.value) focusedTrailingIconColor else unfocusedTrailingIconColor
                            )

                            //密码显示隐藏
                            if (hasPwdIcon) {
                                HorizontalSpace(R.dimen.d10.dimenToDp())
                                Icon(
                                    painter = painterResource(
                                        if (pwdModule.value)
                                            R.drawable.icon_pwd_hide
                                        else
                                            R.drawable.icon_pwd_show
                                    ),
                                    contentDescription = null,
                                    modifier = Modifier.intervalClick {
                                        pwdModule.value = !pwdModule.value

                                    },
                                    tint = if (focus.value) focusedPwdIconColor else unFocusedPwdIconColor
                                )
                            }
                        }
                    }
                    endExtensionView?.let {
                        HorizontalSpace(R.dimen.d10.dimenToDp())
                        it()
                    }

                }
            }
        }
    }

    //外部content变化 修改输入框的内容
    LaunchedEffect(key1 = content) {
        if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
            val regex = decimalPlaces.getNumberRegex(numberType)
            regex.let { reg ->
                if (content.isNotEmpty() && content.matches(reg.toRegex())) {
                    text = content
                } else if (content.isEmpty()) {
                    text = content
                } else {
                    if (errorAnimation) {
                        shake.value = !shake.value
                    }
                    val msg = decimalPlaces.getNumberRegexTip(numberType)
                    toastCenter(msg)
                }
            }
        } else {
            text = content
        }
    }
}


/**
 * 圆角带边框输入框 ,颜色参数可以根据需要进行扩展，默认选中光标直接定位到尾部
 * @param onValueChange:输入框内容变化回调
 * @param content:输入框默认内容
 * @param modifier:自定义样式,默认高度30.dp
 * @param hint:提示文字
 * @param hintColor 提示文字颜色
 * @param hintSize:提示文字大小
 * @param enabled:是否可用
 * @param isError:是否显示错误信息
 * @param errorAnimation 错误信息显示动画
 * @param textStyle:输入框文字样式 颜色 大小 权重 ...,和Text的属性类似
 * @param readOnly:是否只读
 * @param singleLine:是否单行
 * @param cornerRadius:圆角大小
 * @param focusedBorderThickness:焦点状态下输入框边框宽度
 * @param unfocusedBorderThickness:非焦点状态下输入框边框宽度
 * @param hasLeadingIcon:是否显示左侧图标
 * @param leadingIcon 左侧图标
 * @param hasTrailingIcon:是否显示右侧图标
 * @param trailingIcon 右侧图标
 * @param hasPwdIcon:右侧是否有密码图标
 * @param pwdChar 密码占位字符
 * @param focusedTextColor:焦点状态下文字颜色
 * @param unfocusedTextColor:非焦点状态下文字颜色
 * @param cursorColor:光标颜色
 * @param focusedBorderColor:焦点状态下输入框边框颜色
 * @param unfocusedBorderColor:非焦点状态下输入框边框颜色
 * @param focusedContainerColor:焦点状态下输入框背景颜色
 * @param unfocusedContainerColor:非焦点状态下输入框背景颜色
 * @param focusedLeadingIconColor:焦点状态下左侧图标颜色
 * @param unfocusedLeadingIconColor:非焦点状态下左侧图标颜色
 * @param focusedTrailingIconColor:焦点状态下右侧图标颜色
 * @param unfocusedTrailingIconColor:非焦点状态下右侧图标颜色
 * @param focusedPwdIconColor:焦点状态下密码图标颜色
 * @param unFocusedPwdIconColor:非焦点状态下密码图标颜色
 * @param colors:各种颜色，可以使用单参数也可以直接传入颜色值
 * @param horizontalPadding 左侧内边距
 * @param verticalPadding 右侧内边距
 * @param interactionSource:交互源
 * @param maxLines:最大行数
 * @param minLines:最小行数
 * @param imeAction 键盘动作
 * @param keyboardType 键盘类型
 * @param decimalPlaces 小数点位数
 * @param numberType: 数字类型
 * @param keyboardActions 键盘动作回调
 * @param closeKeyBoard:关闭键盘回调
 * @param clearFocus:清除焦点回调
 * @param focusChange :焦点改变回调
 * @param rightAlignment 是否右对齐
 * @param verticalAlignment 垂直对齐方式
 * @param endExtensionView:右侧扩展控件
 * **/

@Composable
fun RoundedCornerOutlinedTextFieldValue(
    modifier: Modifier = Modifier.height(R.dimen.d45.dimenToDp()),
    onValueChange: (String) -> Unit,
    content: String = "",
    hint: String = "",
    hintColor: Color = R.color.gray_99.toComposeColor(),
    hintSize: TextUnit = R.dimen.d12.dimenToSp(),
    enabled: Boolean = true,
    isError: Boolean = false,
    errorAnimation: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    readOnly: Boolean = false,
    singleLine: Boolean = false,
    cornerRadius: Dp = R.dimen.d0.dimenToDp(),
    focusedBorderThickness: Dp = R.dimen.d1.dimenToDp(),
    unfocusedBorderThickness: Dp = R.dimen.d1.dimenToDp(),
    hasLeadingIcon: Boolean = false,
    leadingIcon: Int = R.drawable.icon_search,
    hasTrailingIcon: Boolean = true,
    trailingIcon: Int = R.drawable.icon_edt_clear_gray,
    hasPwdIcon: Boolean = false,//是否有密码图标
    pwdChar: Char = '*',//，密码占位字符
    focusedTextColor: Color = R.color.black_33.toComposeColor(),
    unfocusedTextColor: Color = R.color.black_33.toComposeColor(),
    cursorColor: Color = R.color.blue_2E76EE.toComposeColor(),
    focusedBorderColor: Color = R.color.blue_2E76EE.toComposeColor(),
    unfocusedBorderColor: Color = R.color.gray_99.toComposeColor(),
    focusedContainerColor: Color = R.color.transparent.toComposeColor(),
    unfocusedContainerColor: Color = R.color.transparent.toComposeColor(),
    focusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedLeadingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    unfocusedTrailingIconColor: Color = R.color.gray_99.toComposeColor(),
    focusedPwdIconColor: Color = focusedTrailingIconColor,
    unFocusedPwdIconColor: Color = unfocusedTrailingIconColor,
    colors: TextFieldColors? = null,
    horizontalPadding: Dp = R.dimen.d5.dimenToDp(),
    verticalPadding: Dp = horizontalPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    imeAction: ImeAction = ImeAction.Done,
    keyboardType: KeyboardType = KeyboardType.Text,
    decimalPlaces: Int = 0,
    numberType: NumberType = NumberType.NONE,
    keyboardActions: (String) -> Unit = {},
    closeKeyBoard: (() -> Unit) -> Unit = {},
    clearFocus: (() -> Unit) -> Unit = {},
    focusChange: (Boolean) -> Unit = {},
    rightAlignment: Boolean = false,
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    endExtensionView: @Composable (() -> Unit)? = null
) {
    var text by remember {
        mutableStateOf(
            TextFieldValue(
                text = content,
                selection = TextRange(content.length),
                composition = null
            )
        )
    }
    val softwareKeyboardController = LocalSoftwareKeyboardController.current

    val focusManager = LocalFocusManager.current
    //输入错误动画提示
    val shake = remember { mutableStateOf(false) }
    //键盘关闭
    val close = {
        softwareKeyboardController?.hide()
    }

    //焦点清除
    val clear = {
        focusManager.clearFocus(true)
    }

    //密码是否可见
    val pwdModule = remember { mutableStateOf(false) }

    val visualTransformation = remember(pwdModule.value) {
        if (pwdModule.value) {
            if (pwdChar == PasswordVisualTransformation().mask)
                PasswordVisualTransformation()
            else
                PasswordVisualTransformation(pwdChar)
        } else {
            VisualTransformation.None
        }
    }

    //定义颜色
    val lastColors = colors ?: OutlinedTextFieldDefaults.colors(
        focusedTextColor = focusedTextColor,
        unfocusedTextColor = unfocusedTextColor,
    )

    //定义文本Style，包括文本的颜色、字体大小等,必须要定义，否则使用默认的字体颜色
    val lastTextColor = textStyle.color.takeOrElse {
        val focused = interactionSource.collectIsFocusedAsState().value
        when {
            !enabled -> lastColors.disabledTextColor
            isError -> lastColors.errorTextColor
            focused -> lastColors.focusedTextColor
            else -> lastColors.unfocusedTextColor
        }
    }

    val mergedTextStyle = textStyle.merge(TextStyle(color = lastTextColor))

    //最终的cursorColor
    val lastCursorColor = if (isError) lastColors.errorCursorColor else cursorColor

    //关闭键盘的方法 回调给外部
    closeKeyBoard(close)
    clearFocus(clear)

    val focus = remember { mutableStateOf(false) }


    CompositionLocalProvider(LocalTextSelectionColors provides lastColors.textSelectionColors) {
        BasicTextField(
            value = text,
            onValueChange = {
                if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
                    val regex = decimalPlaces.getNumberRegex(numberType)
                    regex.let { reg ->
                        if (it.text.isNotEmpty() && it.text.matches(reg.toRegex())) {
                            text = it
                            onValueChange(text.text)
                        } else if (it.text.isEmpty()) {
                            text = it
                            onValueChange(text.text)
                        } else {
                            if (errorAnimation) {
                                shake.value = !shake.value
                            }
                            val msg = decimalPlaces.getNumberRegexTip(numberType)
                            toastCenter(msg)
                        }
                    }
                } else {
                    text = it
                    onValueChange(text.text)
                }
            },
            keyboardOptions = KeyboardOptions(
                imeAction = imeAction,
                keyboardType = keyboardType
            ),
            keyboardActions = when (imeAction) {
                ImeAction.Search -> KeyboardActions(
                    onSearch = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )

                ImeAction.Send -> KeyboardActions(
                    onSend = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )

                else -> KeyboardActions(
                    onDone = {
                        softwareKeyboardController?.hide()
                        keyboardActions(text.text)
                    },
                )
            },
            visualTransformation = visualTransformation,
            modifier = modifier.onFocusChanged {
                focus.value = it.isFocused
                focusChange(it.isFocused)
            }.horizonShake(shake),
            enabled = enabled,
            readOnly = readOnly,
            textStyle = mergedTextStyle,
            singleLine = singleLine,
            maxLines = maxLines,
            minLines = minLines,
            interactionSource = interactionSource,
            cursorBrush = SolidColor(lastCursorColor)
        ) { innerTextField ->
            //自定义外观样式：leading trailing pwd...
            Box(
                modifier = Modifier.fillMaxSize()
                    .background(
                        color = if (focus.value) focusedContainerColor else unfocusedContainerColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).border(
                        width = if (focus.value) focusedBorderThickness else unfocusedBorderThickness,
                        color = if (focus.value) focusedBorderColor else unfocusedBorderColor,
                        shape = RoundedCornerShape(cornerRadius)
                    ).padding(
                        horizontal = horizontalPadding,
                        vertical = verticalPadding
                    )
            ) {
                Row(
                    modifier = Modifier.fillMaxSize(),
                    verticalAlignment = verticalAlignment,
                    horizontalArrangement = if (rightAlignment) Arrangement.End else Arrangement.Start
                ) {
                    //leading
                    if (hasLeadingIcon) {
                        Icon(
                            painter = painterResource(leadingIcon),
                            contentDescription = null,
                            tint = if (focus.value) focusedLeadingIconColor else unfocusedLeadingIconColor
                        )
                        HorizontalSpace(5.dp)
                    }

                    //输入框主体部分
                    if (rightAlignment) {
                        Box(
                            contentAlignment = Alignment.CenterEnd
                        ) {
                            if (text.text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    } else {
                        Box(
                            modifier = Modifier.weight(1f),
                            contentAlignment = Alignment.CenterStart
                        ) {
                            if (text.text.isEmpty()) {
                                //hint
                                Text(
                                    text = hint,
                                    color = hintColor,
                                    fontSize = hintSize,
                                    modifier = Modifier.basicMarquee(
                                        iterations = Int.MAX_VALUE
                                    )
                                )
                            }
                            innerTextField()
                        }
                    }

                    if (hasTrailingIcon && text.text.isNotEmpty()) {
                        HorizontalSpace(5.dp)
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            //清除
                            Icon(
                                painter = painterResource(trailingIcon),
                                contentDescription = null,
                                modifier = Modifier.intervalClick {
                                    text = TextFieldValue(
                                        text = "",
                                        selection = TextRange(0, 0)
                                    )
                                    onValueChange(text.text)
                                },
                                tint = if (focus.value) focusedTrailingIconColor else unfocusedTrailingIconColor
                            )

                            //密码显示隐藏
                            if (hasPwdIcon) {
                                HorizontalSpace(R.dimen.d10.dimenToDp())
                                Icon(
                                    painter = painterResource(
                                        if (pwdModule.value)
                                            R.drawable.icon_pwd_hide
                                        else
                                            R.drawable.icon_pwd_show
                                    ),
                                    contentDescription = null,
                                    modifier = Modifier.intervalClick {
                                        pwdModule.value = !pwdModule.value

                                    },
                                    tint = if (focus.value) focusedPwdIconColor else unFocusedPwdIconColor
                                )
                            }
                        }
                    }

                    endExtensionView?.let {
                        HorizontalSpace(R.dimen.d10.dimenToDp())
                        it()
                    }
                }
            }
        }
    }

    //外部content变化 修改输入框的内容
    LaunchedEffect(key1 = content) {
        if (keyboardType == KeyboardType.Number || keyboardType == KeyboardType.Decimal) {
            val regex = decimalPlaces.getNumberRegex(numberType)
            regex.let { reg ->
                if (content.isNotEmpty() && content.matches(reg.toRegex())) {
                    text = TextFieldValue(
                        text = content,
                        selection = TextRange(content.length)
                    )
                } else if (content.isEmpty()) {
                    text = TextFieldValue(
                        text = content,
                        selection = TextRange(content.length)
                    )
                } else {
                    if (errorAnimation) {
                        shake.value = !shake.value
                    }
                    val msg = decimalPlaces.getNumberRegexTip(numberType)
                    toastCenter(msg)
                }
            }
        } else {
            text = TextFieldValue(
                text = content,
                selection = TextRange(content.length)
            )
        }
    }
}
